// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Code generated by sidekick. DO NOT EDIT.

use crate::Result;
#[allow(unused_imports)]
use gax::error::Error;

const DEFAULT_HOST: &str = "https://pubsub.googleapis.com";

mod info {
    const NAME: &str = env!("CARGO_PKG_NAME");
    const VERSION: &str = env!("CARGO_PKG_VERSION");
    lazy_static::lazy_static! {
        pub(crate) static ref X_GOOG_API_CLIENT_HEADER: String = {
            let ac = gaxi::api_header::XGoogApiClient{
                name:          NAME,
                version:       VERSION,
                library_type:  gaxi::api_header::GAPIC,
            };
            ac.grpc_header_value()
        };
    }
}

/// Implements [Publisher](super::stub::Publisher) using a Tonic-generated client.
#[derive(Clone)]
pub struct Publisher {
    inner: gaxi::grpc::Client,
}

impl std::fmt::Debug for Publisher {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        f.debug_struct("Publisher")
            .field("inner", &self.inner)
            .finish()
    }
}

impl Publisher {
    pub async fn new(config: gaxi::options::ClientConfig) -> gax::client_builder::Result<Self> {
        let inner = gaxi::grpc::Client::new(config, DEFAULT_HOST).await?;
        Ok(Self { inner })
    }
}

impl super::stub::Publisher for Publisher {
    async fn publish(
        &self,
        req: crate::model::PublishRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<crate::model::PublishResponse>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.pubsub.v1.Publisher",
                "Publish",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.pubsub.v1.Publisher/Publish");
        let x_goog_request_params = [Some(&req)
            .map(|m| &m.topic)
            .map(|s| s.as_str())
            .map(|v| format!("topic={v}"))]
        .into_iter()
        .flatten()
        .fold(String::new(), |b, p| b + "&" + &p);

        type TR = crate::google::pubsub::v1::PublishResponse;
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, crate::model::PublishResponse>)
    }
}

/// Implements [Subscriber](super::stub::Subscriber) using a Tonic-generated client.
#[derive(Clone)]
pub struct Subscriber {
    inner: gaxi::grpc::Client,
}

impl std::fmt::Debug for Subscriber {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
        f.debug_struct("Subscriber")
            .field("inner", &self.inner)
            .finish()
    }
}

impl Subscriber {
    pub async fn new(config: gaxi::options::ClientConfig) -> gax::client_builder::Result<Self> {
        let inner = gaxi::grpc::Client::new(config, DEFAULT_HOST).await?;
        Ok(Self { inner })
    }
}

impl super::stub::Subscriber for Subscriber {
    async fn modify_ack_deadline(
        &self,
        req: crate::model::ModifyAckDeadlineRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<()>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.pubsub.v1.Subscriber",
                "ModifyAckDeadline",
            ));
            e
        };
        let path =
            http::uri::PathAndQuery::from_static("/google.pubsub.v1.Subscriber/ModifyAckDeadline");
        let x_goog_request_params = [Some(&req)
            .map(|m| &m.subscription)
            .map(|s| s.as_str())
            .map(|v| format!("subscription={v}"))]
        .into_iter()
        .flatten()
        .fold(String::new(), |b, p| b + "&" + &p);

        type TR = ();
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, ()>)
    }

    async fn acknowledge(
        &self,
        req: crate::model::AcknowledgeRequest,
        options: gax::options::RequestOptions,
    ) -> Result<gax::response::Response<()>> {
        use gaxi::prost::ToProto;
        let options = gax::options::internal::set_default_idempotency(options, false);
        let extensions = {
            let mut e = tonic::Extensions::new();
            e.insert(tonic::GrpcMethod::new(
                "google.pubsub.v1.Subscriber",
                "Acknowledge",
            ));
            e
        };
        let path = http::uri::PathAndQuery::from_static("/google.pubsub.v1.Subscriber/Acknowledge");
        let x_goog_request_params = [Some(&req)
            .map(|m| &m.subscription)
            .map(|s| s.as_str())
            .map(|v| format!("subscription={v}"))]
        .into_iter()
        .flatten()
        .fold(String::new(), |b, p| b + "&" + &p);

        type TR = ();
        self.inner
            .execute(
                extensions,
                path,
                req.to_proto().map_err(Error::deser)?,
                options,
                &info::X_GOOG_API_CLIENT_HEADER,
                &x_goog_request_params,
            )
            .await
            .and_then(gaxi::grpc::to_gax_response::<TR, ()>)
    }
}
